﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Data;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace UBCon.Controls
{
    public class WaitProgressBar:ProgressBarBase
    {
        #region Constructors
        
        public WaitProgressBar() 
        {
            startTimer.Interval = TimeSpan.FromMilliseconds(800);
            startTimer.Tick += startTimer_Tick;
        }
        private void startTimer_Tick(object sender, EventArgs e)
        {
            startTimer.Stop();

            for (int i = 0; i < ItemsCount; i++)
            {
                SimplaAnimations[i].Begin();
            }
        }
        #endregion

        #region Properties

        internal static double GetXLocation(DependencyObject obj)
        {
            return (double)obj.GetValue(XLocationProperty);
        }

        internal static void SetXLocation(DependencyObject obj, double value)
        {
            obj.SetValue(XLocationProperty, value);
        }

        // Using a DependencyProperty as the backing store for XLocation.  This enables animation, styling, binding, etc...
        internal static readonly DependencyProperty XLocationProperty =
            DependencyProperty.RegisterAttached("XLocation", typeof(double), typeof(WaitProgressBar), new FrameworkPropertyMetadata(-5.0D, new PropertyChangedCallback(OnXLocationPropertyChanged)));
        #endregion

        #region Depenency Property Changed Callbacks

        private static void OnXLocationPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) 
        {
            Rectangle rectanle = sender as Rectangle;
            (rectanle.RenderTransform as TranslateTransform).X = (double)e.NewValue;
        }
        #endregion

        #region Overrides

        protected override void OnRenderSizeChanged(System.Windows.SizeChangedInfo sizeInfo)
        {
            base.OnRenderSizeChanged(sizeInfo);
            width = sizeInfo.NewSize.Width;
            StartAnimation();
        }

        protected override void BuildSimpleAnimation()
        {
            if (SimplaAnimations.Count > 0)
            {
                for (int i = 0; i < ItemsCount; i++)
                {
                    SimplaAnimations[i].Stop();

                    SimplaAnimations[i].Children.Clear();
                }

                SimplaAnimations[4].Completed -= simpleAnimation_Completed;
            }

            SimplaAnimations.Clear();

            for (int i = 0; i < ItemsCount; i++)
            {
                simpleAnimation = new Storyboard() { AutoReverse = false };

                simpleAnimation.BeginTime = TimeSpan.FromMilliseconds(i * 200);
                DoubleAnimation da = new DoubleAnimation() { EasingFunction = new ExponentialEase() { EasingMode = EasingMode.EaseOut, Exponent = 2 } };
                Storyboard.SetTarget(da, Items[i]);
                Storyboard.SetTargetProperty(da, new PropertyPath(WaitProgressBar.XLocationProperty));
                simpleAnimation.Children.Add(da);
                da.Duration = new Duration(TimeSpan.FromSeconds(0.5));
                da.To = width / 2 - i * Distance - width / 2 * 0.1;

                da = new DoubleAnimation();
                da.BeginTime = TimeSpan.FromSeconds(0.5);
                Storyboard.SetTarget(da, Items[i]);
                Storyboard.SetTargetProperty(da, new PropertyPath(WaitProgressBar.XLocationProperty));
                simpleAnimation.Children.Add(da);
                da.Duration = new Duration(TimeSpan.FromSeconds(1.2));
                da.To = width / 2 - i * Distance + width / 2 * 0.1;

                da = new DoubleAnimation() { EasingFunction = new CubicEase() { EasingMode = EasingMode.EaseOut} };
                da.BeginTime = TimeSpan.FromSeconds(1.7);
                Storyboard.SetTarget(da, Items[i]);
                Storyboard.SetTargetProperty(da, new PropertyPath(WaitProgressBar.XLocationProperty));
                simpleAnimation.Children.Add(da);
                da.Duration = new Duration(TimeSpan.FromSeconds(0.5));
                da.To = width + ItemSize;

                SimplaAnimations.Add(simpleAnimation);
            }
            SimplaAnimations[4].Completed += simpleAnimation_Completed;
        }

        void simpleAnimation_Completed(object sender, EventArgs e)
        {
            for (int i = 0; i < ItemsCount; i++)
            {
                Items[i].ApplyAnimationClock(WaitProgressBar.XLocationProperty, null);
                Items[i].SetValue(WaitProgressBar.XLocationProperty, -ItemSize);
            }
            startTimer.Start();
        }

        protected override void InitializeItems()
        {
            for (int i = 0; i < ItemsCount; i++)
            {
                Rectangle rectangle = new Rectangle() { HorizontalAlignment = System.Windows.HorizontalAlignment.Left, VerticalAlignment = System.Windows.VerticalAlignment.Center};
                BindingOperations.SetBinding
                    (
                        rectangle,
                        Rectangle.WidthProperty,
                        new Binding("ItemSize") { Source = this, Mode = BindingMode.OneWay, NotifyOnSourceUpdated = true }
                    );

                BindingOperations.SetBinding
                    (
                        rectangle,
                        Rectangle.HeightProperty,
                        new Binding("ItemSize") { Source = this, Mode = BindingMode.OneWay, NotifyOnSourceUpdated = true }
                    );
                BindingOperations.SetBinding
                    (
                        rectangle,
                        Rectangle.FillProperty,
                        new Binding("Color") { Source = this, Mode = BindingMode.OneWay, NotifyOnSourceUpdated = true }
                    );

                rectangle.SetValue(WaitProgressBar.XLocationProperty, -5.0D);

                TranslateTransform translate = new TranslateTransform();
                rectangle.RenderTransform = translate;
                
                Items.Add(rectangle);
            }
        }

        #endregion

        #region Private Utilities
        #endregion

        #region Event Handlers
        #endregion

        #region Fields

        private double width=5;
        #endregion

        #region Events
        #endregion
    }
}
